package com.ytjj.qmyx.admin.controller;

import com.alibaba.excel.EasyExcelFactory;
import com.alibaba.excel.metadata.Sheet;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.aliyun.oss.OSSClient;
import com.google.gson.Gson;
import com.kuaidi100.sdk.api.QueryTrack;
import com.kuaidi100.sdk.request.QueryTrackParam;
import com.kuaidi100.sdk.request.QueryTrackReq;
import com.kuaidi100.sdk.response.QueryTrackResp;
import com.kuaidi100.sdk.utils.PropertiesReader;
import com.kuaidi100.sdk.utils.SignUtils;
import com.ytjj.common.api.CommonResult;
import com.ytjj.common.api.ResultCode;
import com.ytjj.common.exception.ApiException;
import com.ytjj.common.model.FileResponse;
import com.ytjj.common.utils.AliyunOSSClientUtil;
import com.ytjj.common.utils.HttpClientUtil;
import com.ytjj.qmyx.admin.annotation.OperLog;
import com.ytjj.qmyx.admin.config.SupplyApiConfig;
import com.ytjj.qmyx.admin.constants.SysLogConstants;
import com.ytjj.qmyx.admin.dao.OrdersDao;
import com.ytjj.qmyx.admin.mapper.YxBankerImportErrorMapper;
import com.ytjj.qmyx.admin.model.Admin;
import com.ytjj.qmyx.admin.model.OrdersDelay;
import com.ytjj.qmyx.admin.model.banker.ImportErrorDto;
import com.ytjj.qmyx.admin.model.banker.YxBankerImportError;
import com.ytjj.qmyx.admin.model.dto.ExpressDto;
import com.ytjj.qmyx.admin.model.request.*;
import com.ytjj.qmyx.admin.service.CustomerService;
import com.ytjj.qmyx.admin.service.MemberService;
import com.ytjj.qmyx.admin.service.OrdersService;
import com.ytjj.qmyx.admin.service.ProductService;
import com.ytjj.qmyx.admin.utils.ExpressDicUtil;
import com.ytjj.qmyx.admin.utils.UserUtil;
import com.ytjj.qmyx.mall.mapper.BankerMapper;
import com.ytjj.qmyx.mall.mapper.BankerOrderMapper;
import com.ytjj.qmyx.mall.mapper.OrdersInfoMapper;
import com.ytjj.qmyx.mall.model.BankerOrder;
import com.ytjj.qmyx.mall.model.BankerOrderExample;
import com.ytjj.qmyx.mall.model.OrdersInfo;
import lombok.extern.slf4j.Slf4j;
import org.apache.logging.log4j.util.Strings;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.util.CollectionUtils;
import org.springframework.util.StringUtils;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

import javax.annotation.Resource;
import java.io.BufferedInputStream;
import java.io.IOException;
import java.math.BigDecimal;
import java.text.SimpleDateFormat;
import java.util.*;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import java.util.stream.Collectors;

@RestController
@RequestMapping("/customerOrder")
@Slf4j
public class CustomerController {

    @Autowired
    private CustomerService customerService;

    @Autowired
    private MemberService memberService;
    @Resource
    private OrdersService ordersService;
    @Resource
    private YxBankerImportErrorMapper yxBankerImportErrorMapper;
    @Resource
    private OrdersInfoMapper ordersInfoMapper;
    @Resource
    private BankerMapper bankerMapper;
    @Resource
    private BankerOrderMapper bankerOrderMapper;
    @Resource
    private OrdersDao ordersDao;
    @Resource
    SupplyApiConfig supplyApiConfig;
    @Resource
    private ProductService productService;

    /**
     * 客服订单详情列表
     * @param customerRequest
     * @return
     */
    @PostMapping("/customerOrderList")
    @OperLog(operModule = "客服管理模块", operDesc = "客服订单详情列表", operType = SysLogConstants.OPERATION_SELECT)
    public CommonResult customerOrderList(@RequestBody CustomerRequest customerRequest) {
        if(StringUtils.isEmpty(customerRequest.getId())&&
                StringUtils.isEmpty(customerRequest.getOrderNo())&&
                StringUtils.isEmpty(customerRequest.getPayType())&&
                StringUtils.isEmpty(customerRequest.getTradeNo())&&
                StringUtils.isEmpty(customerRequest.getUserName())&&
                StringUtils.isEmpty(customerRequest.getUserPhone())){
            return CommonResult.success();
        }
        return CommonResult.success(customerService.getCustomerOrderList(customerRequest));
    }

    /**
     * 客服订单详情列表---new
     * @param request
     * @return
     */
    @PostMapping("/customerOrderListNew")
    @OperLog(operModule = "客服管理模块", operDesc = "客服订单详情列表new", operType = SysLogConstants.OPERATION_SELECT)
    public CommonResult customerOrderListNew(@RequestBody CustomerNewRequest request) {
        if (!CollectionUtils.isEmpty(request.getBankerIds()) && 0 == request.getBankerIds().get(0)) {
            request.setBankerIds(null);
        }
        if(null == request.getOrderInfoId()&&
                StringUtils.isEmpty(request.getOrderNo())&&
                StringUtils.isEmpty(request.getUserName())&&
                StringUtils.isEmpty(request.getUserPhone())&&
                StringUtils.isEmpty(request.getChildOrderNo())&&
                StringUtils.isEmpty(request.getResOrderNo())&&
                null == request.getProductId() &&
                StringUtils.isEmpty(request.getBuyer())){
            return CommonResult.success(new ArrayList<>());
        }
        return CommonResult.success(customerService.getNewCustomerOrderList(request));
    }


    /**
     * 修改订单或者补单的规格
     * @param request
     * @return
     */
    @PostMapping("/updateOrderProductSpec")
    public CommonResult updateOrderProductSpec(@RequestBody UpdateOrderProductSpecRequest request) {
        Integer adminId = UserUtil.getAdminId();
        request.setAdminId(adminId);
       return CommonResult.success(customerService.updateOrderProductSpec(request));
    }

    /**
     * 物流信息
     * @param logisticsRequest
     * @return
     */
    @PostMapping("/getLogisticsInfo")
    public CommonResult getLogisticsInfo(@RequestBody LogisticsRequest logisticsRequest) {
        if (logisticsRequest.getExpressCompanyNo() == null ||
                logisticsRequest.getExpressNo() == null || logisticsRequest.getUserPhone()== null) {
            throw new ApiException("用户手机号、快递公司、快递单号不能为空！");
        } else {
            Map<String,String> request = new HashMap<>();
            request.put("expressCode",logisticsRequest.getExpressCompanyNo());
            request.put("expressNo",logisticsRequest.getExpressNo());
            request.put("tel",logisticsRequest.getUserPhone());
            String result = HttpClientUtil.doGet(supplyApiConfig.getUrl() + "/express/getLogisticsInfo",
                    request, supplyApiConfig.getHeadsMap());
            CommonResult commonResult = JSONObject.parseObject(result, CommonResult.class);
            return commonResult;
        }
    }

    /**
     * 修改订单状态
     * @param orderStatusRequest
     * @return
     */
    @PostMapping("/updateOrderStatus")
    @OperLog(operModule = "客服管理模块", operDesc = "修改订单状态", operType = SysLogConstants.OPERATION_UPDATE)
    public CommonResult updateOrderStatus(@RequestBody OrderStatusRequest orderStatusRequest) {
        customerService.updateOrderStatus(orderStatusRequest);
        return CommonResult.success();
    }

    /**
     * 拦截订单
     * @param id
     * @return
     */
    @GetMapping("/intercept")
    public CommonResult addIntercept (@RequestParam("id") Integer id,
                                      @RequestParam("remarks") String remarks,
                                      @RequestParam(value = "recoveryOrderNo", required = false) String recoveryOrderNo){
        Integer customerId = memberService.getAdmin().getId();
        String customerName = memberService.getAdmin().getName();
        int count = customerService.addIntercept(id, customerId, customerName, remarks, recoveryOrderNo);
        if (count > 0) {
            return CommonResult.success(count);
        } else {
            return CommonResult.failed();
        }
    }

    /**
     * 编辑订单详情
     */
    @PostMapping("/updateOrderInfo")
    @OperLog(operModule = "客服管理模块", operDesc = "修改订单详情信息", operType = SysLogConstants.OPERATION_UPDATE)
    public CommonResult updateOrderInfo(@RequestBody UpdateOrderRequest updateOrderRequest){
        Integer adminId = UserUtil.getAdminId();
        updateOrderRequest.setAdminId(adminId);
        int count = customerService.updateOrderInfo(updateOrderRequest);
        if (count > 0) {
            return CommonResult.success(count);
        } else {
            return CommonResult.failed();
        }
    }

    /**
     * 添加延迟发货备注
     * @param ordersDelay
     * @return
     */
    @PostMapping("/addOrderDelayRemark")
    @OperLog(operModule = "客服管理模块", operDesc = "添加延迟发货备注", operType = SysLogConstants.OPERATION_ADD)
    public CommonResult addOrderDelayRemark(@RequestBody OrdersDelay ordersDelay) {
        return CommonResult.success(customerService.addOrderDelayRemark(ordersDelay));
    }

    /**
     * 客服订单详情列表---new -- 导出订单
     * @param request
     * @return
     */
    @PostMapping("/newOrderExport")
    @OperLog(operModule = "客服管理模块", operDesc = "客服订单详情列表new导出订单", operType = SysLogConstants.OPERATION_SELECT)
    public CommonResult newOrderExport(@RequestBody CustomerNewRequest request) {
        if (!CollectionUtils.isEmpty(request.getBankerIds()) && 0 == request.getBankerIds().get(0)) {
            request.setBankerIds(null);
        }
        if(null == request.getOrderInfoId()&&
                StringUtils.isEmpty(request.getOrderNo())&&
                StringUtils.isEmpty(request.getUserName())&&
                StringUtils.isEmpty(request.getUserPhone())&&
                StringUtils.isEmpty(request.getChildOrderNo())&&
                StringUtils.isEmpty(request.getResOrderNo())){
            return CommonResult.success(new ArrayList<>());
        }
        return CommonResult.success(customerService.newOrderExportList(request));
    }

    /**
     * 导入快递单号
     */
    @PostMapping("newImportOrderList")
    public CommonResult batchImportTwoOrderList(MultipartFile file) throws IOException {
        // 上传到oss
//        this.getImgUrl(file);
        // 导入订单
        Sheet sheet = new Sheet(1, 1, NewImportOrderRequest.class);
        try {
            List<Object> list = EasyExcelFactory.read(new BufferedInputStream(file.getInputStream()), sheet);
            log.debug("表格数据：{}", JSONObject.toJSONString(list));
            int i = ordersService.InsertOrders(list.stream()
                    .map(item -> (NewImportOrderRequest) item)
                    .collect(Collectors.toList()));
            return CommonResult.success("插入:"+list.size(),"成功:"+i);
        } catch (IOException e) {
            e.printStackTrace();
            log.error("导入发生异常：{}", e.getMessage());
        }
        return CommonResult.failed(ResultCode.FAILED);
    }

    /**
     * 导入商品评价
     */
    @PostMapping("/importProductReviews")
    public CommonResult importProductReviews(MultipartFile file)  {
        Sheet sheet = new Sheet(1, 2, ImportProductReviewsRequest.class);
        try {
            List<Object> list = EasyExcelFactory.read(new BufferedInputStream(file.getInputStream()), sheet);
            log.debug("表格数据：{}", JSONObject.toJSONString(list));
            int i = productService.importProductReviews(list.stream()
                    .map(item -> (ImportProductReviewsRequest) item)
                    .collect(Collectors.toList()));
            return CommonResult.success("插入:"+list.size(),"成功:"+i);
        } catch (IOException e) {
            e.printStackTrace();
            log.error("导入发生异常：{}", e.getMessage());
        }
        return CommonResult.failed(ResultCode.FAILED);
    }

    /**
     * @Description 上传文件
     *
     *
     * @Version 1.0
     **/
    public FileResponse getImgUrl(MultipartFile file) {
        if (file.isEmpty()) {
            throw new ApiException("文件不存在");
        }
        // 初始化OssClient
        OSSClient ossClient = AliyunOSSClientUtil.getOSSClient();
        FileResponse fileResponse = AliyunOSSClientUtil.uploadObject2OSS(ossClient, file);
        if (fileResponse == null) {
            throw new ApiException("文件上传失败");
        }
        return fileResponse;
    }

    /**
     * @Description 平台导入核对无误的表格 -> 更新快递信息
     *
     *
     * @Version 1.0
     **/
    @PostMapping("/updateOrdersExpressInfo")
    public CommonResult updateOrdersExpressInfo(MultipartFile file) {
//        YxBanker userInfo = userUtil.getUserInfo();
        Admin admin = UserUtil.getAdmin();
        // 上传到oss
//        FileResponse imgUrl = this.getImgUrl(file);
//        log.info("上传记录：{}", JSONObject.toJSONString(imgUrl));
        // 导入订单
        Sheet sheet = new Sheet(1, 1, NewImportOrderRequest.class);
        try {
            List<Object> list = EasyExcelFactory.read(new BufferedInputStream(file.getInputStream()), sheet);
            log.debug("读到记录条数：{}", list.size());
            List<YxBankerImportError> errorList = new ArrayList<>();
            ImportErrorDto importErrorDto = new ImportErrorDto();
            // 获取快递单号放集合里
            list = list.stream().filter(s -> !StringUtils.isEmpty(((NewImportOrderRequest)s).getExpressNo())).collect(Collectors.toList());
            ordersService.updateOrdersExpressInfo(list.stream()
                    .filter(item -> {
                        NewImportOrderRequest request = (NewImportOrderRequest) item;
                        boolean paramExceptionFlag = false;
                        boolean isContainExpressCompany = false;
                        boolean zeroExpressNoFlag = false;
                        // 参数非法(快递号）
                        if(Strings.isNotEmpty(request.getExpressNo())) {
                            request.setExpressNo(request.getExpressNo().trim());
                            paramExceptionFlag = isSpecialChar(request.getExpressNo());
                        }
                        // 参数为空
                        boolean emptyFlag = StringUtils.isEmpty(request.getExpressNo()) || StringUtils.isEmpty(request.getExpressCode());
                        //
                        // 快递公司是否存在
                        if(Strings.isNotEmpty(request.getExpressCode())) {
                            request.setExpressCode(request.getExpressCode().trim());
                            isContainExpressCompany = ExpressDicUtil.containKey(request.getExpressCode());
                        }
                        if (emptyFlag || paramExceptionFlag || !isContainExpressCompany) {
                            YxBankerImportError yxBankerImportError = new YxBankerImportError();
                            yxBankerImportError.setBankerId(admin.getId());

                            int parseInt = Integer.parseInt(request.getOrderInfoId());
                            OrdersInfo ordersInfo = ordersInfoMapper.selectByPrimaryKey(parseInt);
                            yxBankerImportError.setBankerName(bankerMapper.selectByPrimaryKey(ordersInfo.getBankerId()).getName());

                            yxBankerImportError.setCreateTime(new Date());
                            yxBankerImportError.setOrderNo(((NewImportOrderRequest) item).getOrderNo());
                            // 支付平台
//                            yxBankerImportError.setPlatformId(((NewImportOrderRequest) item).getPaySource());
                            // 状态设置为显示
                            yxBankerImportError.setStatus((byte) 1);
                            // 已经导入过快递
                            List<BankerOrder> bankerOrderList = this.getBankerOrderList(((NewImportOrderRequest) item).getOrderNo());
                            if(bankerOrderList.size() > 0) {
                                yxBankerImportError.setExceptionDes("订单号为" + request.getOrderNo() + "的订单已导入过快递号，请不要重复导入！");
                                yxBankerImportErrorMapper.insertSelective(yxBankerImportError);
                                errorList.add(yxBankerImportError);
                                return false;
                            }
                            if(emptyFlag) {
                                yxBankerImportError.setExceptionDes("快递号为空的订单，快递单号或快递公司为空，请检查后重试！");
                                yxBankerImportErrorMapper.insertSelective(yxBankerImportError);
                                errorList.add(yxBankerImportError);
                                return false;
                            }
                            if(paramExceptionFlag) {
                                yxBankerImportError.setExceptionDes("快递号为" + request.getExpressNo() + "的订单录入的快递号包含特殊字符，请检查后重试！");
                                yxBankerImportErrorMapper.insertSelective(yxBankerImportError);
                                errorList.add(yxBankerImportError);
                                return false;
                            }
//                            if(!isContainExpressCompany) {
//                                yxBankerImportError.setExceptionDes("快递号为" + request.getExpressNo() + "的订单录入的快递公司名称不存在，请检查后重试！");
//                                yxBankerImportErrorMapper.insertSelective(yxBankerImportError);
//                                errorList.add(yxBankerImportError);
//                                return false;
//                            }
                        }
                        return true;
                    })
                    .map(item -> {
                        ((NewImportOrderRequest) item).getExpressNo().trim();
                        ((NewImportOrderRequest) item).getExpressCode().trim();
//                        ((OrdersExpressRequest) item).setBankerId(userInfo.getId());
                        // 加入假快递信息
//                        String idStr = ((NewImportOrderRequest) item).getOrderNo().substring(4, ((NewImportOrderRequest) item).getOrderNo().length());
//                        int id = Integer.valueOf(idStr.trim());
                        String idStr = ((NewImportOrderRequest) item).getOrderInfoId();
                        int id = Integer.parseInt(idStr);
                        OrdersInfo ordersInfo = ordersInfoMapper.selectByPrimaryKey(id);
                        if(ordersInfo != null) {
                            String fakeExpress = ordersInfo.getFakeExpress();
                            if(!StringUtils.isEmpty(fakeExpress)) {
                                List<ExpressDto> expressDtos = JSONArray.parseArray(fakeExpress, ExpressDto.class);
                                ExpressDto expressDto = new ExpressDto();
                                expressDto.setContext("快递小哥已上门揽件");
                                expressDto.setFtime(dateToStr(new Date()));
                                expressDto.setTime(dateToStr(new Date()));
                                expressDto.setStatus(14);
                                expressDto.setDeliveryStatus("已揽件");
                                expressDtos.add(expressDto);
                                ordersInfo.setFakeExpress(JSONObject.toJSONString(expressDtos));
                            }
                            ordersInfoMapper.updateByPrimaryKeySelective(ordersInfo);
                        }
                        return (NewImportOrderRequest) item;
                    })
                    .collect(Collectors.toList()));
            importErrorDto.setErrorCount(errorList.size());
            importErrorDto.setSuccessCount(list.size() - errorList.size());
            importErrorDto.setErrorList(errorList);
            return CommonResult.success(importErrorDto);
        } catch (IOException e) {
            e.printStackTrace();
            log.error("导入发生异常：{}", e.getMessage());
        }
        return CommonResult.failed(ResultCode.FAILED);
    }

    /**
     * 订单重复支付退款
     * @param orderNo
     * @return
     */
    @GetMapping("/repeatOrderRefund")
    public CommonResult repeatOrderRefund(String orderNo){
        return customerService.repeatOrderRefund(orderNo);
    }

    /**
     * 退差价确认接口
     * @param orderNo
     * @return
     */
    @GetMapping("/disparitiesRefundConfirm")
    public CommonResult disparitiesRefundConfirm(@RequestParam(value = "orderNo") String orderNo){
        return customerService.disparitiesRefundConfirm(orderNo);
    }

    /**
     * 订单退差价
     */
    @GetMapping("/disparitiesRefund")
    public CommonResult disparitiesRefund(@RequestParam(value = "orderNo") String orderNo,
                                          @RequestParam(value = "amount") BigDecimal amount,
                                          @RequestParam(value = "orderInfoId") Integer orderInfoId,
                                          @RequestParam(value = "remark",required = false) String remark,
                                          @RequestParam(value = "undertakeParty",required = false) Integer undertakeParty){
        return customerService.disparitiesRefund(orderNo,amount,orderInfoId,remark,undertakeParty);
    }

    /**
     * 订单退差价列表
     */
    @PostMapping("/disparitiesRefundList")
    public CommonResult disparitiesRefundList(@RequestBody  OrderDispatiesRefundListRequest request){
        return CommonResult.success(customerService.disparitiesRefundList(request));
    }

    /**
     * 标记自动退款
     * @return
     */
    @GetMapping("/markRefund")
    public CommonResult markRefund(String childOrderNo,Integer state){
        try {
            customerService.markRefund(childOrderNo, state);
        } catch (Exception e) {
            log.error("标记自动退款报错,{}",e);
            return CommonResult.failed(e.getMessage());
        }
        return CommonResult.success();
    }

    /**
     * 判断是否含有特殊字符
     *
     * @param str
     * @return true为包含，false为不包含
     */
    public static boolean isSpecialChar(String str) {
        // String regEx = "[ _`~!@#$%^&*()+=|{}':;',\\[\\].<>/?~！@#￥%……&*（）——+|{}【】‘；：”“’。，、？]|\n|\r|\t";
        String regEx = "[ _.`~!@#$%^&*()+=|{}':;',\\[\\]<>/?~！@#￥%……&*（）——+|{}【】‘；：”“’。，、？]|\n|\r|\t";
        Pattern p = Pattern.compile(regEx);
        Matcher m = p.matcher(str);
        // 快递单号长度小于6位为非法
        Boolean zeroExpressNoFlag = str.trim().length() < 6;
        return m.find() || zeroExpressNoFlag;
    }
    public static String dateToStr(Date date) {
        SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        String str = format.format(date);
        return str;
    }

    public List<BankerOrder> getBankerOrderList(String orderNo) {
        BankerOrderExample bankerOrderExample = new BankerOrderExample();
        bankerOrderExample.createCriteria().andOrderNoEqualTo(orderNo);
        List<BankerOrder> bankerOrders = bankerOrderMapper.selectByExample(bankerOrderExample);
        bankerOrders  = bankerOrders.stream()
                .filter(item -> !com.alibaba.excel.util.StringUtils.isEmpty(item.getExpressNo()))
                .collect(Collectors.toList());
        return bankerOrders;
    }
}
